#!/usr/bin/envpython
# -*-coding:UTF-8-*-
'''
@File    :   group_router.py
@Contact :   308711822@qq.com
@License :   (C) Copyright 2021-2225, Personal exclusive right.

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2023/2/5 16:07   小钟同学      1.0         None
'''

import abc
import functools
import random
import re

from fastapi import APIRouter
from fastapi.routing import APIRoute
from fastapi import Request
import inspect

from enum import Enum, IntEnum
from typing import (
    Any,
    Callable,
    Coroutine,
    Dict,
    List,
    Optional,
    Sequence,
    Set,
    Tuple,
    Type,
    Union,
)

from fastapi import params
from fastapi.datastructures import Default, DefaultPlaceholder
from fastapi.utils import (
    generate_unique_id,
)
from pydantic.typing import AnyCallable

from starlette import routing
from starlette.responses import JSONResponse, Response, StreamingResponse
from starlette.routing import BaseRoute, Match, Route
from starlette.routing import Mount as Mount  # noqa
from starlette.types import ASGIApp, Scope


from pydantic import BaseModel
from fastapi.encoders import DictIntStrAny, SetIntStr
from fastapi.datastructures import Default
from dataclasses import dataclass

from infirmary_admin_src.infirmary_smart_admin.infirmary_biz.infirmary.businesses.schemas import MODEL_SCHEMA


# from infirmary_src.infirmary_system.infirmary_business.schemas import MODEL_SCHEMA


class ApiRouteArgs(BaseModel):
    path: str
    response_model: Optional[Type[Any]] = None
    status_code: Optional[int] = None
    tags: Optional[List[str]] = None
    dependencies: Optional[Sequence[params.Depends]] = None
    summary: Optional[str] = None
    description: Optional[str] = None
    response_description: str = "Successful Response"
    responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None
    deprecated: Optional[bool] = None
    methods: Optional[Union[Set[str], List[str]]] = None
    operation_id: Optional[str] = None
    response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None
    response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None
    response_model_by_alias: bool = True
    response_model_exclude_unset: bool = False
    response_model_exclude_defaults: bool = False
    response_model_exclude_none: bool = False
    include_in_schema: bool = True
    response_class: Union[Type[Response], DefaultPlaceholder] = Default(
        JSONResponse
    )
    name: Optional[str] = None
    route_class_override: Optional[Type[APIRoute]] = None
    callbacks: Optional[List[Route]] = None
    openapi_extra: Optional[Dict[str, Any]] = None

    class Config:
        arbitrary_types_allowed = True


def RestInjectAPIRouter(prefix: str = "",
                        tags: Optional[List[Union[str, Enum]]] = None,
                        dependencies: Optional[Sequence[params.Depends]] = None,
                        default_response_class: Type[Response] = Default(JSONResponse),
                        responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                        callbacks: Optional[List[BaseRoute]] = None,
                        routes: Optional[List[routing.BaseRoute]] = None,
                        redirect_slashes: bool = True,
                        default: Optional[ASGIApp] = None,
                        dependency_overrides_provider: Optional[Any] = None,
                        route_class: Type[APIRoute] = APIRoute,
                        on_startup: Optional[Sequence[Callable[[], Any]]] = None,
                        on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
                        deprecated: Optional[bool] = None,
                        include_in_schema: bool = True,
                        generate_unique_id_function: Callable[[APIRoute], str] = Default(
                            generate_unique_id
                        )):
    def back(cls):
        cls.prefix = prefix  # 给类添加属性
        cls.tags = tags  # 给类添加属性
        cls.redirect_slashes = redirect_slashes  # 给类添加属性
        cls.deprecated = deprecated  # 给类添加属性
        cls.include_in_schema = include_in_schema  # 给类添加属性
        cls.dependencies = dependencies  # 给类添加属性
        cls.default_response_class = default_response_class  # 给类添加属性
        cls.responses = responses  # 给类添加属性
        cls.callbacks = callbacks  # 给类添加属性
        cls.routes = routes  # 给类添加属性
        cls.default = default  # 给类添加属性
        cls.dependency_overrides_provider = dependency_overrides_provider  # 给类添加属性
        cls.route_class = route_class  # 给类添加属性
        cls.on_startup = on_startup  # 给类添加属性
        cls.on_shutdown = on_shutdown  # 给类添加属性
        cls.generate_unique_id_function = generate_unique_id_function  # 给类添加属性

        return cls

    return back


def RestInjectForAPIRouter(prefix: str = "",
                           dependencies: Optional[Sequence[params.Depends]] = None,
                           redirect_slashes: bool = True,
                           ):
    def back(cls):
        cls.prefix = prefix  # 给类添加属性
        cls.dependencies = dependencies  # 给类添加属性
        cls.redirect_slashes = redirect_slashes  # 给类添加属性
        return cls

    return back


def RestInjectForDocRouter(tags: Optional[List[Union[str, Enum]]] = None,
                           deprecated: Optional[bool] = None,
                           include_in_schema: bool = True,
                           ):
    def back(cls):
        cls.tags = tags  # 给类添加属性
        cls.deprecated = deprecated  # 给类添加属性
        cls.include_in_schema = include_in_schema  # 给类添加属性
        return cls

    return back


class RestControllerPrefixApiArgs(BaseModel):
    prefix: str = ""

    class Config:
        arbitrary_types_allowed = True


def RestControllerPrefixApi(prefix: str = ""):
    def back(cls):
        # cls.prefix = prefix  # 给类添加属性
        route_args = RestControllerPrefixApiArgs(
            prefix=prefix)
        setattr(cls, '_prefix_api_args', route_args)
        return cls

    return back


class RestControllerOtherApiArgs(BaseModel):
    dependencies: Optional[Sequence[params.Depends]] = None
    default_response_class: Type[Response] = Default(JSONResponse)
    responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None
    callbacks: Optional[List[BaseRoute]] = None
    routes: Optional[List[routing.BaseRoute]] = None
    default: Optional[ASGIApp] = None
    dependency_overrides_provider: Optional[Any] = None
    route_class: Type[APIRoute] = APIRoute
    on_startup: Optional[Sequence[Callable[[], Any]]] = None
    on_shutdown: Optional[Sequence[Callable[[], Any]]] = None
    generate_unique_id_function: Callable[[APIRoute], str] = Default(
        generate_unique_id
    )

    class Config:
        arbitrary_types_allowed = True


def RestControllerOtherApi(
        dependencies: Optional[Sequence[params.Depends]] = None,
        default_response_class: Type[Response] = Default(JSONResponse),
        responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
        callbacks: Optional[List[BaseRoute]] = None,
        routes: Optional[List[routing.BaseRoute]] = None,
        default: Optional[ASGIApp] = None,
        dependency_overrides_provider: Optional[Any] = None,
        route_class: Type[APIRoute] = APIRoute,
        on_startup: Optional[Sequence[Callable[[], Any]]] = None,
        on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
        generate_unique_id_function: Callable[[APIRoute], str] = Default(
            generate_unique_id
        )):
    def back(cls):
        route_args = RestControllerOtherApiArgs(
            dependencies=dependencies,
            default_response_class=default_response_class,
            responses=responses,
            callbacks=callbacks,
            routes=routes,
            default=default,
            dependency_overrides_provider=dependency_overrides_provider,
            route_class=route_class,
            on_startup=on_startup,
            on_shutdown=on_shutdown,
            generate_unique_id_function=generate_unique_id_function)
        setattr(cls, '_other_api_args', route_args)
        # cls._other_api_args =
        # cls.dependencies = dependencies  # 给类添加属性
        # cls.default_response_class = default_response_class  # 给类添加属性
        # cls.responses = responses  # 给类添加属性
        # cls.callbacks = callbacks  # 给类添加属性
        # cls.routes = routes  # 给类添加属性
        # cls.default = default  # 给类添加属性
        # cls.dependency_overrides_provider = dependency_overrides_provider  # 给类添加属性
        # cls.route_class = route_class  # 给类添加属性
        # cls.on_startup = on_startup  # 给类添加属性
        # cls.on_shutdown = on_shutdown  # 给类添加属性
        # cls.generate_unique_id_function = generate_unique_id_function  # 给类添加属性
        return cls

    return back


class RestControllerDocumentApiArgs(BaseModel):
    tags: Optional[List[Union[str, Enum]]] = None
    redirect_slashes: bool = True
    deprecated: Optional[bool] = None
    include_in_schema: bool = True

    class Config:
        arbitrary_types_allowed = True


def RestControllerDocumentApi(
        tags: Optional[List[Union[str, Enum]]] = None,
        redirect_slashes: bool = True,
        deprecated: Optional[bool] = None,
        include_in_schema: bool = True):
    def back(cls):
        route_args = RestControllerDocumentApiArgs(
            tags=tags,
            redirect_slashes=redirect_slashes,
            deprecated=deprecated,
            include_in_schema=include_in_schema)
        setattr(cls, '_document_api_args', route_args)

        # cls.tags = tags  # 给类添加属性
        # cls.redirect_slashes = redirect_slashes  # 给类添加属性
        # cls.deprecated = deprecated  # 给类添加属性
        # cls.include_in_schema = include_in_schema  # 给类添加属性
        return cls

    return back


def RestRoute(path: str,
              methods: Optional[List[str]] = None,
              response_model: Optional[Type[Any]] = None,
              status_code: Optional[int] = None,
              tags: Optional[List[Union[str, Enum]]] = None,
              dependencies: Optional[Sequence[params.Depends]] = None,
              summary: Optional[str] = None,
              description: Optional[str] = None,
              response_description: str = "Successful Response",
              responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
              deprecated: Optional[bool] = None,
              operation_id: Optional[str] = None,
              response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
              response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
              response_model_by_alias: bool = True,
              response_model_exclude_unset: bool = False,
              response_model_exclude_defaults: bool = False,
              response_model_exclude_none: bool = False,
              include_in_schema: bool = True,
              response_class: Type[Response] = Default(JSONResponse),
              name: Optional[str] = None,
              callbacks: Optional[List[BaseRoute]] = None,
              openapi_extra: Optional[Dict[str, Any]] = None,
              **kwargs: Any):
    def call_func(fun: AnyCallable) -> Callable[[AnyCallable], AnyCallable]:
        route_args = ApiRouteArgs(path=path,
                                  name=name,
                                  status_code=status_code,
                                  methods=methods,
                                  tags=tags,
                                  dependencies=dependencies,
                                  description=description,
                                  summary=summary,
                                  response_description=response_description,
                                  responses=responses,
                                  deprecated=deprecated,
                                  operation_id=operation_id,
                                  response_model_include=response_model_include,
                                  response_model_exclude=response_model_exclude,
                                  response_model_by_alias=response_model_by_alias,
                                  response_model_exclude_unset=response_model_exclude_unset,
                                  response_model_exclude_defaults=response_model_exclude_defaults,
                                  response_model_exclude_none=response_model_exclude_none,
                                  include_in_schema=include_in_schema,
                                  response_class=response_class,
                                  callbacks=callbacks,
                                  openapi_extra=openapi_extra,
                                  response_model=response_model,
                                  **kwargs)

        setattr(fun, '_route_endpoint_fun', fun)
        if not hasattr(fun, '_route_args'):
            setattr(fun, '_route_args', route_args)
        else:
            pass
        return fun

    return call_func


def RestRouteGet(path: str,
                 response_model: Optional[Type[Any]] = None,
                 status_code: Optional[int] = None,
                 tags: Optional[List[Union[str, Enum]]] = None,
                 dependencies: Optional[Sequence[params.Depends]] = None,
                 summary: Optional[str] = None,
                 description: Optional[str] = None,
                 response_description: str = "Successful Response",
                 responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                 deprecated: Optional[bool] = None,
                 operation_id: Optional[str] = None,
                 response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                 response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                 response_model_by_alias: bool = True,
                 response_model_exclude_unset: bool = False,
                 response_model_exclude_defaults: bool = False,
                 response_model_exclude_none: bool = False,
                 include_in_schema: bool = True,
                 response_class: Type[Response] = Default(JSONResponse),
                 name: Optional[str] = None,
                 callbacks: Optional[List[BaseRoute]] = None,
                 openapi_extra: Optional[Dict[str, Any]] = None,
                 **kwargs: Any):
    return RestRoute(
        path=path,
        name=name,
        status_code=status_code,
        methods=["GET"],
        tags=tags,
        dependencies=dependencies,
        description=description,
        summary=summary,
        response_description=response_description,
        responses=responses,
        deprecated=deprecated,
        operation_id=operation_id,
        response_model_include=response_model_include,
        response_model_exclude=response_model_exclude,
        response_model_by_alias=response_model_by_alias,
        response_model_exclude_unset=response_model_exclude_unset,
        response_model_exclude_defaults=response_model_exclude_defaults,
        response_model_exclude_none=response_model_exclude_none,
        include_in_schema=include_in_schema,
        response_class=response_class,
        callbacks=callbacks,
        openapi_extra=openapi_extra,
        response_model=response_model,
        **kwargs
    )


def RestRoutePost(path: str,
                  response_model: Optional[Type[Any]] = None,
                  status_code: Optional[int] = None,
                  tags: Optional[List[Union[str, Enum]]] = None,
                  dependencies: Optional[Sequence[params.Depends]] = None,
                  summary: Optional[str] = None,
                  description: Optional[str] = None,
                  response_description: str = "Successful Response",
                  responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                  deprecated: Optional[bool] = None,
                  operation_id: Optional[str] = None,
                  response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                  response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                  response_model_by_alias: bool = True,
                  response_model_exclude_unset: bool = False,
                  response_model_exclude_defaults: bool = False,
                  response_model_exclude_none: bool = False,
                  include_in_schema: bool = True,
                  response_class: Type[Response] = Default(JSONResponse),
                  name: Optional[str] = None,
                  callbacks: Optional[List[BaseRoute]] = None,
                  openapi_extra: Optional[Dict[str, Any]] = None,
                  **kwargs: Any):
    return RestRoute(
        path=path,
        name=name,
        status_code=status_code,
        methods=["POST"],
        tags=tags,
        dependencies=dependencies,
        description=description,
        summary=summary,
        response_description=response_description,
        responses=responses,
        deprecated=deprecated,
        operation_id=operation_id,
        response_model_include=response_model_include,
        response_model_exclude=response_model_exclude,
        response_model_by_alias=response_model_by_alias,
        response_model_exclude_unset=response_model_exclude_unset,
        response_model_exclude_defaults=response_model_exclude_defaults,
        response_model_exclude_none=response_model_exclude_none,
        include_in_schema=include_in_schema,
        response_class=response_class,
        callbacks=callbacks,
        openapi_extra=openapi_extra,
        response_model=response_model,
        **kwargs
    )


def RestRoutePatch(path: str,
                   response_model: Optional[Type[Any]] = None,
                   status_code: Optional[int] = None,
                   tags: Optional[List[Union[str, Enum]]] = None,
                   dependencies: Optional[Sequence[params.Depends]] = None,
                   summary: Optional[str] = None,
                   description: Optional[str] = None,
                   response_description: str = "Successful Response",
                   responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                   deprecated: Optional[bool] = None,
                   operation_id: Optional[str] = None,
                   response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                   response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                   response_model_by_alias: bool = True,
                   response_model_exclude_unset: bool = False,
                   response_model_exclude_defaults: bool = False,
                   response_model_exclude_none: bool = False,
                   include_in_schema: bool = True,
                   response_class: Type[Response] = Default(JSONResponse),
                   name: Optional[str] = None,
                   callbacks: Optional[List[BaseRoute]] = None,
                   openapi_extra: Optional[Dict[str, Any]] = None,
                   **kwargs: Any):
    return RestRoute(
        path=path,
        name=name,
        status_code=status_code,
        methods=["PATCH"],
        tags=tags,
        dependencies=dependencies,
        description=description,
        summary=summary,
        response_description=response_description,
        responses=responses,
        deprecated=deprecated,
        operation_id=operation_id,
        response_model_include=response_model_include,
        response_model_exclude=response_model_exclude,
        response_model_by_alias=response_model_by_alias,
        response_model_exclude_unset=response_model_exclude_unset,
        response_model_exclude_defaults=response_model_exclude_defaults,
        response_model_exclude_none=response_model_exclude_none,
        include_in_schema=include_in_schema,
        response_class=response_class,
        callbacks=callbacks,
        openapi_extra=openapi_extra,
        response_model=response_model,
        **kwargs
    )


def RestRoutePut(path: str,
                 response_model: Optional[Type[Any]] = None,
                 status_code: Optional[int] = None,
                 tags: Optional[List[Union[str, Enum]]] = None,
                 dependencies: Optional[Sequence[params.Depends]] = None,
                 summary: Optional[str] = None,
                 description: Optional[str] = None,
                 response_description: str = "Successful Response",
                 responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                 deprecated: Optional[bool] = None,
                 operation_id: Optional[str] = None,
                 response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                 response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                 response_model_by_alias: bool = True,
                 response_model_exclude_unset: bool = False,
                 response_model_exclude_defaults: bool = False,
                 response_model_exclude_none: bool = False,
                 include_in_schema: bool = True,
                 response_class: Type[Response] = Default(JSONResponse),
                 name: Optional[str] = None,
                 callbacks: Optional[List[BaseRoute]] = None,
                 openapi_extra: Optional[Dict[str, Any]] = None,
                 **kwargs: Any):
    return RestRoute(
        path=path,
        name=name,
        status_code=status_code,
        methods=["PUT"],
        tags=tags,
        dependencies=dependencies,
        description=description,
        summary=summary,
        response_description=response_description,
        responses=responses,
        deprecated=deprecated,
        operation_id=operation_id,
        response_model_include=response_model_include,
        response_model_exclude=response_model_exclude,
        response_model_by_alias=response_model_by_alias,
        response_model_exclude_unset=response_model_exclude_unset,
        response_model_exclude_defaults=response_model_exclude_defaults,
        response_model_exclude_none=response_model_exclude_none,
        include_in_schema=include_in_schema,
        response_class=response_class,
        callbacks=callbacks,
        openapi_extra=openapi_extra,
        response_model=response_model,
        **kwargs
    )


def RestRouteDelete(path: str,
                    response_model: Optional[Type[Any]] = None,
                    status_code: Optional[int] = None,
                    tags: Optional[List[Union[str, Enum]]] = None,
                    dependencies: Optional[Sequence[params.Depends]] = None,
                    summary: Optional[str] = None,
                    description: Optional[str] = None,
                    response_description: str = "Successful Response",
                    responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
                    deprecated: Optional[bool] = None,
                    operation_id: Optional[str] = None,
                    response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                    response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
                    response_model_by_alias: bool = True,
                    response_model_exclude_unset: bool = False,
                    response_model_exclude_defaults: bool = False,
                    response_model_exclude_none: bool = False,
                    include_in_schema: bool = True,
                    response_class: Type[Response] = Default(JSONResponse),
                    name: Optional[str] = None,
                    callbacks: Optional[List[BaseRoute]] = None,
                    openapi_extra: Optional[Dict[str, Any]] = None,
                    **kwargs: Any):
    return RestRoute(
        path=path,
        name=name,
        status_code=status_code,
        methods=["DELETE"],
        tags=tags,
        dependencies=dependencies,
        description=description,
        summary=summary,
        response_description=response_description,
        responses=responses,
        deprecated=deprecated,
        operation_id=operation_id,
        response_model_include=response_model_include,
        response_model_exclude=response_model_exclude,
        response_model_by_alias=response_model_by_alias,
        response_model_exclude_unset=response_model_exclude_unset,
        response_model_exclude_defaults=response_model_exclude_defaults,
        response_model_exclude_none=response_model_exclude_none,
        include_in_schema=include_in_schema,
        response_class=response_class,
        callbacks=callbacks,
        openapi_extra=openapi_extra,
        response_model=response_model,
        **kwargs
    )


def RestParameter(modelss: Type[MODEL_SCHEMA]):
    def call_func(fun: AnyCallable) -> Callable[[AnyCallable], AnyCallable]:
        # 判断是否存在存在路由属性
        if hasattr(fun, '_route_args'):
            route_args: ApiRouteArgs = getattr(fun, '_route_args')

            # 要注入的模型对象依赖项
            def depends_set_model_(request: Request):
                request.state.parameter_model = modelss
                return request

            # 定义依赖项
            parameter: Optional[params.Depends] = Depends(depends_set_model_)
            # 添加依赖项到依赖项列表中
            if route_args.dependencies:
                list(route_args.dependencies).append(parameter)
            else:
                route_args.dependencies = [
                    Depends(depends_set_model_)]

        return fun

    return call_func


def RestServicesInject(servicename: str, service=None):
    def call_func(fun: AnyCallable) -> Callable[[AnyCallable], AnyCallable]:
        if hasattr(fun, '_route_args'):
            route_args: ApiRouteArgs = getattr(fun, '_route_args')

            class ServicesContent:
                def __init__(self, content: str):
                    self.content = content

                def __call__(self):
                    return "测试" + self.content

            def depends_set_model_(request: Request,
                                   test: ServicesContent = Depends(ServicesContent(content='你是谁'))):
                setattr(request.state, servicename, test)
                return request

            parameter: Optional[params.Depends] = Depends(depends_set_model_)
            if route_args.dependencies:
                list(route_args.dependencies).append(parameter)
            else:
                route_args.dependencies = [Depends(depends_set_model_)]
        return fun

    return call_func


def RestRequestParameterInject(modelss: Type[MODEL_SCHEMA]):
    '''
    通过装饰器模型透传一个请求上下文对象到对应的request.state中
    :param modelss:
    :return:
    '''

    def call_func(fun: AnyCallable) -> Callable[[AnyCallable], AnyCallable]:
        if hasattr(fun, '_route_args'):
            route_args: ApiRouteArgs = getattr(fun, '_route_args')

            def depends_set_model_(request: Request):
                request.state.parameter_model = modelss
                return request

            parameter: Optional[params.Depends] = Depends(depends_set_model_)
            route_args.dependencies = list(route_args.dependencies).append(parameter) if route_args.dependencies else [
                Depends(depends_set_model_)]
        return fun

    return call_func


class HookRequestRoute(APIRoute):

    @abc.abstractmethod
    async def before_request(self, request: Request, curr_apiroute: APIRoute) -> None:
        """如果需要修改请求信息，可直接重写此方法"""
        raise NotImplemented

    @abc.abstractmethod
    async def after_request(self, request: Request, response: Response) -> None:
        """请求后的处理【记录请求耗时等，注意这里没办法对响应结果进行处理】"""
        raise NotImplemented

    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            response_info = None
            try:
                # before_request 函数回调
                await self.before_request(curr_apiroute=self, request=request)
                response_info = await original_route_handler(request)
                return response_info
            finally:
                response = None
                if response_info:
                    # 响应报文的封装
                    print(isinstance(response_info,StreamingResponse))
                    if isinstance(response_info,StreamingResponse):
                        response =  response_info
                    else:

                        try:
                            response = Response(content=response_info.body,
                                                status_code=response_info.status_code,
                                                headers=dict(response_info.headers)
                                                )
                        except Exception as e:
                            response = response_info
                # after_request 函数回调
                await self.after_request(request=request, response=response)
                pass

        return custom_route_handler


from fastapi import Depends


class IHookBaseController(metaclass=abc.ABCMeta):

    def __init__(self):
        self.api_router = None

    @property
    def cls(self):
        return type(self)

    @property
    def this_router_api(self):
        return self.api_router

    @abc.abstractmethod
    async def before_request(self, request: Request, curr_apiroute: APIRoute) -> None:
        """如果需要修改请求信息，可直接重写此方法"""
        raise NotImplemented

    @abc.abstractmethod
    async def after_request(self, request: Request, response: Response) -> None:
        """请求后的处理【记录请求耗时等，注意这里没办法对响应结果进行处理】"""
        raise NotImplemented

    def _creat_api_router(self) -> APIRouter:
        pass
        if not self.api_router:
            pass
            # prefix: str = "",
            # tags: Optional[List[Union[str, Enum]]] = None,
            # dependencies: Optional[Sequence[params.Depends]] = None,
            # default_response_class: Type[Response] = Default(JSONResponse),
            # responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
            # callbacks: Optional[List[BaseRoute]] = None,
            # routes: Optional[List[routing.BaseRoute]] = None,
            # redirect_slashes: bool = True,
            # default: Optional[ASGIApp] = None,
            # dependency_overrides_provider: Optional[Any] = None,
            # route_class: Type[APIRoute] = APIRoute,
            # on_startup: Optional[Sequence[Callable[[], Any]]] = None,
            # on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
            # deprecated: Optional[bool] = None,
            # include_in_schema: bool = True,
            # generate_unique_id_function: Callable[[APIRoute], str] = Default(
            #     generate_unique_id
            # ),
            self.api_router = APIRouter(
                prefix=getattr(self.cls, 'prefix', None) or "",
                tags=getattr(self.cls, 'tags', None) or None,
                dependencies=getattr(self.cls, 'dependencies', None) or None,
                default_response_class=getattr(self.cls, 'default_response_class', None) or Default(JSONResponse),
                responses=getattr(self.cls, 'responses', None) or None,
                callbacks=getattr(self.cls, 'callbacks', None) or None,
                routes=getattr(self.cls, 'routes', None) or None,
                redirect_slashes=getattr(self.cls, 'redirect_slashes', None) or True,
                default=getattr(self.cls, 'default', None) or None,
                dependency_overrides_provider=getattr(self.cls, 'dependency_overrides_provider', None) or None,
                route_class=getattr(self.cls, 'route_class', None) or APIRoute,
                on_startup=getattr(self.cls, 'on_startup', None) or None,
                on_shutdown=getattr(self.cls, 'on_shutdown', None) or None,
                deprecated=getattr(self.cls, 'deprecated', None) or None,
                include_in_schema=getattr(self.cls, 'include_in_schema', None) or True,
                generate_unique_id_function=getattr(self.cls, 'generate_unique_id_function', None) or Default(
                    generate_unique_id
                ),
            )
            # 设置回调处理
            setattr(HookRequestRoute, 'before_request', self.before_request)
            setattr(HookRequestRoute, 'after_request', self.after_request)
            self.api_router.route_class = HookRequestRoute
        return self.api_router

    def _register_endpoint(self) -> APIRouter:
        # 获取当前注入的APIRouter对象
        assert hasattr(self, 'api_router'), '需要实例化APIRouter对象'
        # 获取当前注入的APIRouter对象
        self._creat_api_router()
        # 通过inspect.getmembers（或for i in dir(self.cls)）查询当前类下下定义对应的特定特点包含有被标记了_endpoint属性的路由函数
        for name, route_endpoint in inspect.getmembers(self.cls, inspect.isfunction):
            if hasattr(route_endpoint, '_route_endpoint_fun'):
                # 判断是否被标记
                route_endpoint = getattr(route_endpoint, '_route_endpoint_fun')
                # 路由参数对象信息
                route_args: ApiRouteArgs = getattr(route_endpoint, '_route_args')
                # 传递self对象到对应_endpoint函数对象
                curr_route_endpoint_fun = functools.partial(route_endpoint, self)
                # 注意事项---处理经过functools.partial后丢失__name__的问题
                # setattr(curr_route_endpoint_fun, '__name__', route_endpoint.__name__)
                # 这里需要注意同名函数的情况下会覆盖的问题，
                route_args.name = route_args.name or route_endpoint.__name__

                def cleandoc():
                    # 注意清理的对象curr_route_endpoint_fun
                    curr_route_endpoint_fun.__doc__ = ''

                # 函数注释说明信息。文档显示描述问题处理
                # 获取对象的文档注释
                # inspect.getdoc(route_endpoint)
                route_args.description = route_args.description or inspect.getdoc(route_endpoint) or cleandoc()

                # 开始添加当前被被RestRoute给注册的端点函数

                def generate_unique_id(route: "APIRoute") -> str:
                    operation_id = route.name + route.path_format
                    operation_id = re.sub(r"\W", "_", operation_id)
                    assert route.methods
                    operation_id = f"{operation_id}_{list(route.methods)[0].lower()}"
                    return operation_id

                self.api_router.add_api_route(**route_args.dict(),
                                              endpoint=curr_route_endpoint_fun,
                                              generate_unique_id_function=Default(generate_unique_id))
                # 删除绑定属性
                delattr(route_endpoint, '_route_endpoint_fun')
                delattr(route_endpoint, '_route_args')

        # for i in dir(self.cls):
        #     # 获取到注册到函数中的对应_endpoint函数对象
        #     route_endpoint = getattr(self.cls, i)
        #     # 判断是否是被RestRoute给注册的端点函数
        #     if (inspect.isfunction(route_endpoint) or inspect.iscoroutinefunction(route_endpoint)) and hasattr(
        #             route_endpoint, '_route_endpoint_fun'):
        #         # 如果是指定的端点函数对象，透传当前self到当前的函数中
        #         # 要获取到对应的_endpoint绑定的函数，不能直接的获取getattr(self.cls, i)，不然会出现丢失__name__问题
        #         route_endpoint = getattr(route_endpoint, '_route_endpoint_fun')
        #         # 路由参数对象信息
        #         route_args: ApiRouteArgs = getattr(route_endpoint, '_route_args')
        #         # 传递self对象到对应_endpoint函数对象
        #         curr_route_endpoint_fun = functools.partial(route_endpoint, self)
        #         # 注意事项---处理经过functools.partial后丢失__name__的问题
        #         # setattr(curr_route_endpoint_fun, '__name__', route_endpoint.__name__)
        #         # 这里需要注意同名函数的情况下会覆盖的问题，
        #         route_args.name = route_args.name or route_endpoint.__name__
        #         def cleandoc():
        #             # 注意清理的对象curr_route_endpoint_fun
        #             curr_route_endpoint_fun.__doc__ = ''
        #         # 函数注释说明信息。文档显示描述问题处理
        #         # 获取对象的文档注释
        #         # inspect.getdoc(route_endpoint)
        #         route_args.description = route_args.description or inspect.getdoc(route_endpoint) or cleandoc()
        #
        #         # 开始添加当前被被RestRoute给注册的端点函数
        #
        #         def generate_unique_id(route: "APIRoute") -> str:
        #             operation_id = route.name + route.path_format
        #             operation_id = re.sub(r"\W", "_", operation_id)
        #             assert route.methods
        #             operation_id = f"{operation_id}_{list(route.methods)[0].lower()}"
        #             return operation_id
        #
        #         self.api_router.add_api_route(**route_args.dict(),
        #                                       endpoint=curr_route_endpoint_fun,
        #                                       generate_unique_id_function=Default(generate_unique_id))
        return self.api_router

    def build(self) -> APIRouter:
        #  注册点点路由
        return self._register_endpoint()

    @classmethod
    def instance(cls) -> APIRouter:
        """实例化"""
        return cls().build()
